from sqlalchemy import Column, String, Integer, ForeignKey, DateTime, Enum, Text, Float, Table, Boolean
from sqlalchemy.orm import relationship, backref
from enum import Enum as PyEnum

from app.models.base import Base

# 项目-用户关联表（项目团队成员）
project_user = Table(
    "project_user",
    Base.metadata,
    Column("project_id", Integer, ForeignKey("project.id"), primary_key=True),
    Column("user_id", Integer, ForeignKey("user.id"), primary_key=True),
)


class ProjectStatus(PyEnum):
    PLANNING = "planning"  # 规划中
    INITIATING = "initiating"  # 启动中
    EXECUTING = "executing"  # 执行中
    MONITORING = "monitoring"  # 监控中
    CLOSING = "closing"  # 结束中
    COMPLETED = "completed"  # 已完成
    ON_HOLD = "on_hold"  # 已暂停
    CANCELLED = "cancelled"  # 已取消


class PhaseStatus(PyEnum):
    NOT_STARTED = "not_started"  # 未开始
    IN_PROGRESS = "in_progress"  # 进行中
    COMPLETED = "completed"  # 已完成
    DELAYED = "delayed"  # 已延期
    ON_HOLD = "on_hold"  # 已暂停


class TaskStatus(PyEnum):
    NOT_STARTED = "not_started"  # 未开始
    IN_PROGRESS = "in_progress"  # 进行中
    COMPLETED = "completed"  # 已完成
    DELAYED = "delayed"  # 已延迟
    BLOCKED = "blocked"  # 已阻塞
    CANCELLED = "cancelled"  # 已取消


class TaskPriority(PyEnum):
    LOW = "low"  # 低
    MEDIUM = "medium"  # 中
    HIGH = "high"  # 高
    URGENT = "urgent"  # 紧急


class Program(Base):
    """项目集模型"""
    name = Column(String(100), nullable=False, index=True)
    description = Column(Text, nullable=True)
    start_date = Column(DateTime, nullable=True)
    end_date = Column(DateTime, nullable=True)
    status = Column(String(20), nullable=False, default=ProjectStatus.PLANNING.value)
    
    # 关系
    projects = relationship("Project", back_populates="program")


class Project(Base):
    """项目模型"""
    name = Column(String(100), nullable=False, index=True)
    code = Column(String(20), nullable=False, unique=True, index=True)  # 项目编码
    description = Column(Text, nullable=True)
    start_date = Column(DateTime, nullable=True)
    planned_end_date = Column(DateTime, nullable=True)  # 计划结束日期
    actual_end_date = Column(DateTime, nullable=True)   # 实际结束日期
    status = Column(String(20), nullable=False, default=ProjectStatus.PLANNING.value)
    budget = Column(Float, nullable=True)  # 预算
    actual_cost = Column(Float, nullable=True)  # 实际成本
    progress = Column(Float, default=0.0)  # 进度百分比
    priority = Column(Integer, default=0)  # 优先级（数字越大优先级越高）
    
    # 外键
    program_id = Column(Integer, ForeignKey("program.id"), nullable=True)
    manager_id = Column(Integer, ForeignKey("user.id"), nullable=True)
    creator_id = Column(Integer, ForeignKey("user.id"), nullable=False)  # 创建者
    
    # 关系
    program = relationship("Program", back_populates="projects")
    manager = relationship("User", foreign_keys=[manager_id], back_populates="managed_projects")
    creator = relationship("User", foreign_keys=[creator_id], back_populates="created_projects")
    phases = relationship("Phase", back_populates="project")
    tasks = relationship("Task", back_populates="project")
    team_members = relationship("User", secondary=project_user)
    risks = relationship("Risk", back_populates="project")
    issues = relationship("Issue", back_populates="project")
    documents = relationship("Document", back_populates="project")
    milestones = relationship("Milestone", back_populates="project")
    reports = relationship("Report", back_populates="project")
    resources = relationship("Resource", secondary="resource_project", back_populates="projects")


class Phase(Base):
    """项目阶段模型"""
    name = Column(String(100), nullable=False)
    description = Column(Text, nullable=True)
    start_date = Column(DateTime, nullable=True)
    end_date = Column(DateTime, nullable=True)
    status = Column(String(20), nullable=False, default=PhaseStatus.NOT_STARTED.value)
    order = Column(Integer, nullable=False, default=0)  # 阶段顺序
    
    # 外键
    project_id = Column(Integer, ForeignKey("project.id"), nullable=False)
    
    # 关系
    project = relationship("Project", back_populates="phases")
    tasks = relationship("Task", back_populates="phase")
    milestones = relationship("Milestone", back_populates="phase")


class Milestone(Base):
    """里程碑模型"""
    name = Column(String(100), nullable=False)
    description = Column(Text, nullable=True)
    due_date = Column(DateTime, nullable=False)
    completed = Column(Boolean, default=False)
    completed_date = Column(DateTime, nullable=True)  # 完成日期
    
    # 外键
    project_id = Column(Integer, ForeignKey("project.id"), nullable=False)  # 项目ID
    phase_id = Column(Integer, ForeignKey("phase.id"), nullable=True)  # 阶段ID（可选）
    
    # 关系
    phase = relationship("Phase", back_populates="milestones")


class Task(Base):
    """任务模型"""
    name = Column(String(100), nullable=False, index=True)
    description = Column(Text, nullable=True)
    status = Column(String(20), nullable=False, default=TaskStatus.NOT_STARTED.value)
    priority = Column(String(20), nullable=False, default=TaskPriority.MEDIUM.value)
    start_date = Column(DateTime, nullable=True)
    due_date = Column(DateTime, nullable=True)
    completed_date = Column(DateTime, nullable=True)
    estimated_hours = Column(Float, nullable=True)
    actual_hours = Column(Float, nullable=True, default=0)
    progress = Column(Float, nullable=False, default=0)  # 0-100的进度百分比
    
    # 外键
    project_id = Column(Integer, ForeignKey("project.id"), nullable=False)
    phase_id = Column(Integer, ForeignKey("phase.id"), nullable=True)
    milestone_id = Column(Integer, ForeignKey("milestone.id"), nullable=True)  # 里程碑ID
    assignee_id = Column(Integer, ForeignKey("user.id"), nullable=True)
    creator_id = Column(Integer, ForeignKey("user.id"), nullable=False)  # 创建者
    parent_id = Column(Integer, ForeignKey("task.id"), nullable=True)  # 父任务ID
    
    # 关系
    project = relationship("Project", back_populates="tasks")
    phase = relationship("Phase", back_populates="tasks")
    assignee = relationship("User", back_populates="tasks")
    documents = relationship("Document", back_populates="task")
    subtasks = relationship("Task", backref=backref("parent", remote_side=[id]))
    dependencies = relationship(
        "TaskDependency",
        foreign_keys="[TaskDependency.task_id]",
        back_populates="task"
    )
    dependents = relationship(
        "TaskDependency",
        foreign_keys="[TaskDependency.dependency_id]",
        back_populates="dependency"
    )
    comments = relationship("TaskComment", back_populates="task")


class TaskDependency(Base):
    """任务依赖关系模型"""
    # 外键
    task_id = Column(Integer, ForeignKey("task.id"), primary_key=True)
    dependency_id = Column(Integer, ForeignKey("task.id"), primary_key=True)
    dependency_type = Column(String(20), nullable=False, default="finish_to_start")  # 依赖类型
    
    # 关系
    task = relationship("Task", foreign_keys=[task_id], back_populates="dependencies")
    dependency = relationship("Task", foreign_keys=[dependency_id], back_populates="dependents")


class TaskComment(Base):
    """任务评论模型"""
    content = Column(Text, nullable=False)
    
    # 外键
    task_id = Column(Integer, ForeignKey("task.id"), nullable=False)
    user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
    
    # 关系
    task = relationship("Task", back_populates="comments")
    user = relationship("User")